home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / unix / tracker_4_3.lzh / tracker / Amiga / audio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-13  |  9.8 KB  |  383 lines

  1. /* audio.c 
  2.     vi:se ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: audio.c,v 1.8 1994/01/12 16:12:34 espie Exp espie $
  6.  * $Log: audio.c,v $
  7.  * Revision 1.8  1994/01/12  16:12:34  espie
  8.  * Last minute changes.
  9.  *
  10.  * Revision 4.1  1994/01/12  16:12:34  espie
  11.  * Last minute changes.
  12.  *
  13.  * Revision 4.1  1994/01/12  16:10:20  espie
  14.  * Fixed up last minute problems.
  15.  *
  16.  * Revision 4.0  1994/01/11  17:39:36  espie
  17.  * Lots of changes.
  18.  *
  19.  * Revision 1.5  1994/01/09  17:36:22  Espie
  20.  * Generalized open.c.
  21.  *
  22.  * Revision 1.4  1994/01/08  03:55:43  Espie
  23.  * Just new names, provide for better !
  24.  *
  25.  * Revision 1.3  1994/01/05  14:54:09  Espie
  26.  * *** empty log message ***
  27.  *
  28.  * Revision 1.2  1993/12/28  13:54:44  Espie
  29.  * Finally corrected irksome probleme with MAX_PITCH.
  30.  *
  31.  * Revision 1.1  1993/12/26  00:55:53  Espie
  32.  * Initial revision
  33.  *
  34.  * Revision 3.10  1993/12/04  16:12:50  espie
  35.  * First changes to augment the number of channels.
  36.  *
  37.  * Revision 3.9  1993/11/17  15:30:16  espie
  38.  * Added one level of abstraction. Look through player.c for the
  39.  * old high-level functions.
  40.  *
  41.  * Revision 3.8  1993/08/04  11:34:33  espie
  42.  * *** empty log message ***
  43.  *
  44.  * Revision 3.7  1993/07/18  10:39:44  espie
  45.  * Cleaned up some code.
  46.  *
  47.  * Revision 3.6  1992/11/27  10:29:00  espie
  48.  * General cleanup
  49.  *
  50.  * Revision 3.5  1992/11/24  10:51:19  espie
  51.  * Optimized output and fixed up some details.
  52.  * Unrolled code for oversample = 1 to be more efficient at
  53.  * higher frequency (since a high frequency is better than
  54.  * a higher oversample).
  55.  *
  56.  * Revision 3.4  1992/11/23  17:18:59  espie
  57.  * *** empty log message ***
  58.  *
  59.  * Revision 3.3  1992/11/23  10:12:23  espie
  60.  * Fixed up BIG bug.
  61.  *
  62.  * Revision 3.2  1992/11/20  14:53:32  espie
  63.  * Added finetune.
  64.  *
  65.  * Revision 3.1  1992/11/19  20:44:47  espie
  66.  * Protracker commands.
  67.  *
  68.  * Revision 3.0  1992/11/18  16:08:05  espie
  69.  * New release.
  70.  *
  71.  * Revision 2.14  1992/11/06  19:31:53  espie
  72.  * Fixed missing parameter type.
  73.  * fix_xxx for better speed.
  74.  * set_volume.
  75.  * Added possibility to get back to MONO for the sgi.
  76.  * Added stereo capabilities to the indigo version.
  77.  * Minor bug: a SAMPLE_FAULT is a minor error,
  78.  * we should first check that there was no other
  79.  * error before setting it.
  80.  * New resample function coming from the player.
  81.  * Added more notes.
  82.  *
  83.  * Revision 2.1  1991/11/17  23:07:58  espie
  84.  * Just computes some frequency-related parameters.
  85.  *
  86.  *
  87.  */
  88.  
  89. #include <math.h>
  90. #ifndef __386BSD__
  91. #include <malloc.h>
  92. #else
  93. #include <stdlib.h>
  94. #endif
  95. #include <stdio.h>
  96.  
  97. #include "defs.h"
  98. #include "song.h"
  99. #include "channel.h"
  100. #include "extern.h"
  101.      
  102. ID("$Id: audio.c,v 1.8 1994/01/12 16:12:34 espie Exp espie $")
  103.  
  104.  
  105. /* DO_NOTHING is also used for the automaton */
  106. #define DO_NOTHING 0
  107. #define PLAY 1
  108. #define REPLAY 2
  109.  
  110. #define MAX_CHANNELS 8
  111.  
  112. LOCAL struct audio_channel
  113.    {
  114.    struct sample_info *samp;
  115.    int mode;
  116.    unsigned long pointer;
  117.    unsigned long step;
  118.    int volume;
  119.    int pitch;
  120.    } chan[MAX_CHANNELS];
  121.  
  122. LOCAL struct sample_info dummy =
  123.    {
  124.    NULL,
  125.    0,
  126.    0,
  127.    0,
  128.    0,
  129.    0,
  130.    0,
  131.    0,
  132.    NULL,
  133.    NULL
  134.    };
  135.  
  136. LOCAL int allocated = 0;
  137.  
  138. struct audio_channel *new_channel_tag_list(prop)
  139. struct tag *prop;
  140.    {
  141.    struct audio_channel *new;
  142.    new = &chan[allocated++];
  143.    new->mode = DO_NOTHING;
  144.    new->pointer = 0;
  145.    new->step = 0;
  146.    new->pitch = 0;
  147.    new->volume = 0;
  148.    new->samp = &dummy;
  149.    return new;
  150.    }
  151.  
  152. void release_audio_channels()
  153.    {
  154.    allocated = 0;
  155.    }
  156.  
  157. /* Have to get some leeway for vibrato (since we don't bound pitch with
  158.  * vibrato). This is conservative.
  159.  */
  160. #define VIB_MAXDEPTH 150
  161.  
  162.  
  163. #define C fix_to_int(ch->pointer)
  164.  
  165. LOCAL unsigned long step_table[REAL_MAX_PITCH + VIB_MAXDEPTH];  
  166.                   /* holds the increment for finding the next sampled
  167.                    * byte at a given pitch (see resample() ).
  168.                    */
  169.  
  170. /* creates a table for converting ``amiga'' pitch
  171.  * to a step rate at a given resampling frequency.
  172.  * For accuracy, we don't use floating point, but
  173.  * instead fixed point ( << ACCURACY).
  174.  * IMPORTANT NOTE: we need to make it fit within 32 bits (long), which
  175.  * must be enough for ACCURACY + log2(max sample length)
  176.  */
  177. LOCAL void create_step_table(oversample, output_fr)
  178. int oversample;     /* we sample oversample i for each byte output */
  179. int output_fr;      /* output frequency */
  180.    {
  181.    double note_fr; /* note frequency (in Hz) */
  182.    double step;
  183.    int pitch;      /* amiga pitch */
  184.  
  185.    step_table[0] = 0;
  186.    for (pitch = 1; pitch < REAL_MAX_PITCH + VIB_MAXDEPTH; pitch++)
  187.       {
  188.       note_fr = AMIGA_CLOCKFREQ / pitch;
  189.          /* int_to_fix(1) is the normalizing factor */
  190.       step = note_fr / output_fr * int_to_fix(1) / oversample;
  191.       step_table[pitch] = (long)step;
  192.       }
  193.    }
  194.          
  195. LOCAL void readjust_pitch()
  196.    {
  197.    int i;
  198.    for (i = 0; i < allocated; i++)
  199.       chan[i].step = step_table[chan[i].pitch];
  200.    }
  201.  
  202. void init_tables(oversample, frequency)
  203. int oversample, frequency;
  204.    {
  205.    create_step_table(oversample, frequency);
  206.    readjust_pitch();
  207.    }
  208.  
  209.  
  210. /* The playing mechanism itself.
  211.  * According to the current channel automaton,
  212.  * we resample the instruments in real time to
  213.  * generate output.
  214.  */
  215. void resample(oversample, number)
  216. int oversample;
  217. int number;
  218.    {
  219.    int i;            /* sample counter */
  220.    int channel;      /* channel counter */
  221.    int sampling;     /* oversample counter */
  222.    int value[NUMBER_TRACKS];
  223.                      /* recombinations of the various data */
  224.    struct audio_channel *ch;
  225.  
  226.       /* safety check: we can't have a segv there, provided
  227.        * chan points to a valid sample.
  228.        * For `empty' samples, what is needed is fix_length = 0
  229.        * and rp_start = NULL
  230.        */
  231.    /* special case optimization */
  232.    if (oversample == 1)
  233.       {
  234.          /* do the resampling, i.e., actually play sounds */
  235.       for (i = 0; i < number; i++) 
  236.          {
  237.          for (channel = 0; channel < allocated; channel++)
  238.             {
  239.             ch = chan + channel;
  240.             switch(ch->mode)
  241.                {
  242.             case DO_NOTHING:
  243.                value[channel] = 0;
  244.                break;
  245.             case PLAY:
  246.                   /* Since we now have fix_length, we can
  247.                    * do that check with improved performance
  248.                    */
  249.                if (ch->pointer < ch->samp->fix_length)
  250.                   {
  251.                   value[channel] = ch->samp->start[C] * ch->volume;
  252.                   ch->pointer += ch->step;
  253.                   break;
  254.                   }
  255.                else
  256.                   {
  257.                   ch->mode = REPLAY;
  258.                   ch->pointer -= ch->samp->fix_length;
  259.                   /* FALLTHRU */
  260.                   }
  261.             case REPLAY:
  262.                      /* is there a replay ? */
  263.                if (!ch->samp->rp_start)
  264.                   {
  265.                   ch->mode = DO_NOTHING;
  266.                   break;
  267.                   }
  268.                while (ch->pointer >= ch->samp->fix_rp_length)
  269.                   ch->pointer -= ch->samp->fix_rp_length;
  270.                value[channel] = ch->samp->rp_start[C] * ch->volume;
  271.                ch->pointer += ch->step;
  272.                break;
  273.                }
  274.             } 
  275.          output_samples(value[0]+value[3], value[1]+value[2]);
  276.          }
  277.       }   
  278.    else
  279.       {
  280.       for (i = 0; i < number; i++) 
  281.          {
  282.          for (channel = 0; channel < allocated; channel++)
  283.             {
  284.             value[channel] = 0;
  285.             for (sampling = 0; sampling < oversample; sampling++)
  286.                {
  287.                ch = chan + channel;
  288.                switch(ch->mode)
  289.                   {
  290.                case DO_NOTHING:
  291.                   break;
  292.                case PLAY:
  293.                      /* Since we now have fix_length, we can
  294.                       * do that check with improved performance
  295.                       */
  296.                   if (ch->pointer < ch->samp->fix_length)
  297.                      {
  298.                      value[channel] += ch->samp->start[C] * ch->volume;
  299.                      ch->pointer += ch->step;
  300.                      break;
  301.                      }
  302.                   else
  303.                      {
  304.                      ch->mode = REPLAY;
  305.                      ch->pointer -= ch->samp->fix_length;
  306.                      /* FALLTHRU */
  307.                      }
  308.                case REPLAY:
  309.                         /* is there a replay ? */
  310.                   if (!ch->samp->rp_start)
  311.                      {
  312.                      ch->mode = DO_NOTHING;
  313.                      break;
  314.                      }
  315.                   while (ch->pointer >= ch->samp->fix_rp_length)
  316.                      ch->pointer -= ch->samp->fix_rp_length;
  317.                   value[channel] += ch->samp->rp_start[C] * ch->volume;
  318.                   ch->pointer += ch->step;
  319.                   break;
  320.                   }
  321.                } 
  322.             }
  323.          output_samples((value[0]+value[3])/oversample, 
  324.             (value[1]+value[2])/oversample);
  325.          }   
  326.       }
  327.  
  328.    flush_buffer();
  329.    }
  330.  
  331.  
  332. /* setting up a given note */
  333.  
  334. void play_note(au, samp, pitch)
  335. struct audio_channel *au;
  336. struct sample_info *samp;
  337. int pitch;
  338.    {
  339.    au->pointer = 0;
  340.    au->pitch = pitch;
  341.    au->step = step_table[pitch];
  342.    if (samp)
  343.       {
  344.       au->samp = samp;
  345.       au->mode = PLAY;
  346.       }
  347.    else
  348.       au->mode = DO_NOTHING;
  349.    }
  350.  
  351. /* changing the current pitch (value
  352.  * may be temporary, and not stored
  353.  * in channel pitch, for instance vibratos.
  354.  */
  355. void set_play_pitch(au, pitch)
  356. struct audio_channel *au;
  357. int pitch;
  358.    {
  359.       /* save current pitch in case we want to change
  360.        * the step table on the run
  361.        */
  362.    au->pitch = pitch;
  363.    au->step = step_table[pitch];
  364.    }
  365.  
  366. /* changing the current volume. You HAVE to get through
  367.  * there so that it will work on EVERY machine.
  368.  */
  369. void set_play_volume(au, volume)
  370. struct audio_channel *au;
  371. int volume;
  372.    {
  373.    au->volume = volume;
  374.    }
  375.  
  376. void set_play_position(au, pos)
  377. struct audio_channel *au;
  378. int pos;
  379.    {
  380.    au->pointer = int_to_fix(pos);
  381.    }
  382.  
  383.